package com.fqy.ticket.business.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.fqy.ticket.common.exception.BusinessException;
import com.fqy.ticket.common.exception.BusinessExceptionEnum;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class RedissonLockTestService {

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    Logger LOG = LoggerFactory.getLogger(RedissonLockTestService.class);

    /**
     * 使用 Redisson 实现分布式锁
     */
    public void processWithLock(String req) throws InterruptedException {
        String lockKey = req + ":" + DateUtil.formatDate(DateTime.now());
        RLock lock = null;

        try {
            // 获取锁对象
            lock = redissonClient.getLock(lockKey);

            // 尝试获取锁（不等待，自动续期）
            boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);

            // 查看锁的结构
            // inspectLockStructure(lockKey);

            if (tryLock) {
                // 获取锁成功，执行业务逻辑
                LOG.info("恭喜，抢到锁了！lockKey：{}", lockKey);
                try {
                    long currentThreadId = Thread.currentThread().getId();
                    LOG.info("当前线程ID: {}", currentThreadId);

                    // 获取锁对象
                    lock = redissonClient.getLock(lockKey);

                    // 执行业务逻辑（例如：处理订单、扣减库存等）
                    Thread.sleep(100000);
                } finally {
                    // 释放锁
                    if (lock.isHeldByCurrentThread()) {
                        lock.unlock();
                        LOG.info("锁已释放！lockKey：{}", lockKey);
                    }
                }
            } else {
                // 获取锁失败
                LOG.info("很遗憾，没抢到锁！lockKey：{}", lockKey);
                throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
            }
        } catch (InterruptedException e) {
            // 处理中断异常
            Thread.currentThread().interrupt();
            LOG.error("获取锁被中断", e);
            throw e;
        }
    }
}